import crypto from 'crypto';
import CryptoJS from 'crypto-js';
import dayjs from 'dayjs';
import FileLogger from './file-logger';

const logger = new FileLogger('handle-crypto.ts');

export const md5 = (val: string) => {
  const secret = crypto.createHash('md5').update(val).digest('hex');
  return secret;
};
export const sha1 = (val: string) => {
  const secret = crypto.createHash('sha1').update(val).digest('hex');
  return secret;
};

export const handlePassword = (password: string): string => md5(password);

const KEY = '/45694d696b6f/eimiko';

//解密方法
export function aesDecode(word: string, key: string = KEY, rawIv?: string) {
  try {
    // 解析秘钥偏移量
    const iv = rawIv
      ? CryptoJS.enc.Utf8.parse(rawIv)
      : CryptoJS.enc.Utf8.parse(dayjs().format('~YYYY~MM~DD~HH~~')); // 十六位十六进制数作为秘钥偏移量

    const keyEnc = CryptoJS.enc.Utf8.parse(key); // 解析加密秘钥

    const encryptedHexStr = CryptoJS.enc.Hex.parse(word); // 解析十六进制的密文
    const srcs = CryptoJS.enc.Base64.stringify(encryptedHexStr); // 将密文转换为Base64格式的字符串

    const decrypt = CryptoJS.AES.decrypt(srcs, keyEnc, {
      iv: iv,
      mode: CryptoJS.mode.CBC,
      padding: CryptoJS.pad.Pkcs7,
    }); // 解密操作

    const decryptedStr = decrypt.toString(CryptoJS.enc.Utf8); // 将解密后的数据转换为UTF-8格式的字符串
    return JSON.parse(decryptedStr.toString()); // 将字符串解析为JSON对象并返回
  } catch (err) {
    logger.printError('aesDecode', err); // 在解密过程中捕获异常，并打印错误信息
    return null;
  }
}

//加密方法
export function aesEncode(raw: any, key: string = KEY, rawIv?: string) {
  const iv = rawIv
    ? CryptoJS.enc.Utf8.parse(rawIv)
    : CryptoJS.enc.Utf8.parse(dayjs().format('~YYYY~MM~DD~HH~~'));
  const word = JSON.stringify(raw);
  const srcs = CryptoJS.enc.Utf8.parse(word);
  const keyEnc = CryptoJS.enc.Utf8.parse(key);
  const encrypted = CryptoJS.AES.encrypt(srcs, keyEnc, {
    iv: iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7,
  });
  return encrypted.ciphertext.toString().toUpperCase();
}

export function buildDingPushUrl(webhook: string, secret: string) {
  const timestamp = Date.now();
  const stringToSign = timestamp + '\n' + secret;
  const sign = crypto
    .createHmac('sha256', secret)
    .update(stringToSign)
    .digest('base64');
  const sign_urlencode = encodeURIComponent(sign);
  const url = webhook + `&timestamp=${timestamp}&sign=${sign_urlencode}`;
  return url;
}
